<!DOCTYPE html>
<html lang=zh>
<head>
    <!-- so meta -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="HandheldFriendly" content="True">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5" />
    <meta name="description" content="什么是缓存呢？ 当我们第一次访问网站的时候，比如 juejin.cn，电脑会把网站上的图片和数据下载到电脑上，当我们再次访问该网站的时候，网站就会从电脑中直接加载出来，这就是缓存。 缓存有哪些好处？  缓解服务器压力，不用每次都去请求某些数据了。  提升性能，打开本地资源肯定会比请求服务器来的快。  减少带宽消耗，当我们使用缓存时，只会产生很小的网络消耗，至于为什么打开本地资源也会产生网络消耗，下">
<meta property="og:type" content="article">
<meta property="og:title" content="浏览器缓存">
<meta property="og:url" content="https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/index.html">
<meta property="og:site_name" content="柯里的语法糖">
<meta property="og:description" content="什么是缓存呢？ 当我们第一次访问网站的时候，比如 juejin.cn，电脑会把网站上的图片和数据下载到电脑上，当我们再次访问该网站的时候，网站就会从电脑中直接加载出来，这就是缓存。 缓存有哪些好处？  缓解服务器压力，不用每次都去请求某些数据了。  提升性能，打开本地资源肯定会比请求服务器来的快。  减少带宽消耗，当我们使用缓存时，只会产生很小的网络消耗，至于为什么打开本地资源也会产生网络消耗，下">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/20220306145630.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/20220306145714.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220216161804242.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220216161818821.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/20220306145815.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/20220306145848.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220216161428643.png">
<meta property="article:published_time" content="2022-02-10T16:00:00.000Z">
<meta property="article:modified_time" content="2022-03-07T04:01:37.363Z">
<meta property="article:author" content="柯里的语法糖">
<meta property="article:tag" content="浏览器">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/20220306145630.png">
    
    
      
        
          <link rel="shortcut icon" href="https://codertzm.oss-cn-chengdu.aliyuncs.com/favicon.ico">
        
      
      
        
          <link rel="icon" type="image/png" href="https://codertzm.oss-cn-chengdu.aliyuncs.com/favicon.ico" sizes="192x192">
        
      
      
        
          <link rel="apple-touch-icon" sizes="180x180" href="https://codertzm.oss-cn-chengdu.aliyuncs.com/favicon.ico">
        
      
    
    <!-- title -->
    <title>浏览器缓存</title>
    <!-- styles -->
    
<link rel="stylesheet" href="/css/style.css">

    <!-- persian styles -->
    
    <!-- rss -->
    
    
	<!-- mathjax -->
	
<meta name="generator" content="Hexo 6.0.0"></head>

<body class="max-width mx-auto px3 ltr">
    
      <div id="header-post">
  <a id="menu-icon" href="#" aria-label="Menu"><i class="fas fa-bars fa-lg"></i></a>
  <a id="menu-icon-tablet" href="#" aria-label="Menu"><i class="fas fa-bars fa-lg"></i></a>
  <a id="top-icon-tablet" href="#" aria-label="Top" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');" style="display:none;"><i class="fas fa-chevron-up fa-lg"></i></a>
  <span id="menu">
    <span id="nav">
      <ul>
        <!--
       --><li><a href="/">首页</a></li><!--
     --><!--
       --><li><a href="/tags/">标签</a></li><!--
     --><!--
       --><li><a href="/categories/">分类</a></li><!--
     --><!--
       --><li><a href="/archives/">归档</a></li><!--
     --><!--
       --><li><a target="_blank" rel="noopener" href="http://github.com/twitzz">项目</a></li><!--
     --><!--
       --><li><a href="/about/">关于</a></li><!--
     --><!--
       --><li><a href="/search/">搜索</a></li><!--
     -->
      </ul>
    </span>
    <br/>
    <span id="actions">
      <ul>
        
        <li><a class="icon" aria-label="上一篇" href="/2022/03/05/JavaScript/array/"><i class="fas fa-chevron-left" aria-hidden="true" onmouseover="$('#i-prev').toggle();" onmouseout="$('#i-prev').toggle();"></i></a></li>
        
        
        <li><a class="icon" aria-label="下一篇" href="/2022/02/07/frontend/dynamicLoad_route/"><i class="fas fa-chevron-right" aria-hidden="true" onmouseover="$('#i-next').toggle();" onmouseout="$('#i-next').toggle();"></i></a></li>
        
        <li><a class="icon" aria-label="返回顶部" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');"><i class="fas fa-chevron-up" aria-hidden="true" onmouseover="$('#i-top').toggle();" onmouseout="$('#i-top').toggle();"></i></a></li>
        <li><a class="icon" aria-label="分享文章" href="#"><i class="fas fa-share-alt" aria-hidden="true" onmouseover="$('#i-share').toggle();" onmouseout="$('#i-share').toggle();" onclick="$('#share').toggle();return false;"></i></a></li>
      </ul>
      <span id="i-prev" class="info" style="display:none;">上一篇</span>
      <span id="i-next" class="info" style="display:none;">下一篇</span>
      <span id="i-top" class="info" style="display:none;">返回顶部</span>
      <span id="i-share" class="info" style="display:none;">分享文章</span>
    </span>
    <br/>
    <div id="share" style="display: none">
      <ul>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.facebook.com/sharer.php?u=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/"><i class="fab fa-facebook " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://twitter.com/share?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&text=浏览器缓存"><i class="fab fa-twitter " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.linkedin.com/shareArticle?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&title=浏览器缓存"><i class="fab fa-linkedin " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://pinterest.com/pin/create/bookmarklet/?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&is_video=false&description=浏览器缓存"><i class="fab fa-pinterest " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="mailto:?subject=浏览器缓存&body=Check out this article: https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/"><i class="fas fa-envelope " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://getpocket.com/save?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&title=浏览器缓存"><i class="fab fa-get-pocket " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://reddit.com/submit?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&title=浏览器缓存"><i class="fab fa-reddit " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.stumbleupon.com/submit?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&title=浏览器缓存"><i class="fab fa-stumbleupon " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://digg.com/submit?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&title=浏览器缓存"><i class="fab fa-digg " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.tumblr.com/share/link?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&name=浏览器缓存&description="><i class="fab fa-tumblr " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://news.ycombinator.com/submitlink?u=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&t=浏览器缓存"><i class="fab fa-hacker-news " aria-hidden="true"></i></a></li>
</ul>

    </div>
    <div id="toc">
      <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%BC%BA%E7%BC%93%E5%AD%98"><span class="toc-number">1.</span> <span class="toc-text">强缓存</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A6%82%E4%BD%95%E8%AE%BE%E7%BD%AE%E5%BC%BA%E7%BC%93%E5%AD%98"><span class="toc-number">1.1.</span> <span class="toc-text">如何设置强缓存</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%8E%A7%E5%88%B6%E7%BC%93%E5%AD%98%E7%9A%84%E5%AD%97%E6%AE%B5"><span class="toc-number">1.2.</span> <span class="toc-text">控制缓存的字段</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#expires"><span class="toc-number">1.2.1.</span> <span class="toc-text">expires</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Cache-Control"><span class="toc-number">1.2.2.</span> <span class="toc-text">Cache-Control</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#pragma"><span class="toc-number">1.2.3.</span> <span class="toc-text">pragma</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BC%93%E5%AD%98%E4%BD%8D%E7%BD%AE"><span class="toc-number">2.</span> <span class="toc-text">缓存位置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Service-Worker"><span class="toc-number">2.1.</span> <span class="toc-text">Service Worker</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Memory-Cache"><span class="toc-number">2.2.</span> <span class="toc-text">Memory Cache</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Disk-Cache"><span class="toc-number">2.3.</span> <span class="toc-text">Disk Cache</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#prefetch-cache-%E9%A2%84%E5%8F%96%E7%BC%93%E5%AD%98"><span class="toc-number">2.4.</span> <span class="toc-text">prefetch cache(预取缓存)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Push-Cache"><span class="toc-number">2.5.</span> <span class="toc-text">Push Cache</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8D%8F%E5%95%86%E7%BC%93%E5%AD%98"><span class="toc-number">3.</span> <span class="toc-text">协商缓存</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A6%82%E4%BD%95%E8%AE%BE%E7%BD%AE%E5%8D%8F%E5%95%86%E7%BC%93%E5%AD%98"><span class="toc-number">3.1.</span> <span class="toc-text">如何设置协商缓存</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Last-Modified-If-Modified-Since"><span class="toc-number">3.1.1.</span> <span class="toc-text">Last-Modified &#x2F; If-Modified-Since</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Etag-If-None-Match"><span class="toc-number">3.1.2.</span> <span class="toc-text">Etag &#x2F; If-None-Match</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%BC%BA%E7%BC%93%E5%AD%98%E4%B8%8E%E5%8D%8F%E5%95%86%E7%BC%93%E5%AD%98%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">4.</span> <span class="toc-text">强缓存与协商缓存的区别</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BC%93%E5%AD%98%E6%96%B9%E6%A1%88"><span class="toc-number">5.</span> <span class="toc-text">缓存方案</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%88%B7%E6%96%B0%E5%AF%B9%E4%BA%8E%E5%BC%BA%E7%BC%93%E5%AD%98%E5%92%8C%E5%8D%8F%E5%95%86%E7%BC%93%E5%AD%98%E7%9A%84%E5%BD%B1%E5%93%8D"><span class="toc-number">6.</span> <span class="toc-text">刷新对于强缓存和协商缓存的影响</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%BB%E7%BB%93"><span class="toc-number">7.</span> <span class="toc-text">总结</span></a></li></ol>
    </div>
  </span>
</div>

    
    <div class="content index py4">
        
        <article class="post" itemscope itemtype="http://schema.org/BlogPosting">
  <header>
    
    <h1 class="posttitle" itemprop="name headline">
        浏览器缓存
    </h1>



    <div class="meta">
      <span class="author" itemprop="author" itemscope itemtype="http://schema.org/Person">
        <span itemprop="name">柯里的语法糖</span>
      </span>
      
    <div class="postdate">
      
        <time datetime="2022-02-10T16:00:00.000Z" itemprop="datePublished">2022-02-11</time>
        
      
    </div>


      
    <div class="article-category">
        <i class="fas fa-archive"></i>
        <a class="category-link" href="/categories/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/">性能优化</a>
    </div>


      
    <div class="article-tag">
        <i class="fas fa-tag"></i>
        <a class="tag-link-link" href="/tags/%E6%B5%8F%E8%A7%88%E5%99%A8/" rel="tag">浏览器</a>
    </div>


    </div>
  </header>
  

  <div class="content" itemprop="articleBody">
    <p>什么是缓存呢？</p>
<p>当我们第一次访问网站的时候，比如 juejin.cn，电脑会把网站上的图片和数据下载到电脑上，当我们再次访问该网站的时候，网站就会从电脑中直接加载出来，这就是缓存。</p>
<p>缓存有哪些好处？</p>
<ol>
<li><p>缓解服务器压力，不用每次都去请求某些数据了。</p>
</li>
<li><p>提升性能，打开本地资源肯定会比请求服务器来的快。</p>
</li>
<li><p>减少带宽消耗，当我们使用缓存时，只会产生很小的网络消耗，至于为什么打开本地资源也会产生网络消耗，下面会有说明。</p>
</li>
</ol>
<p><strong>浏览器缓存过程： 强缓存，协商缓存</strong>。</p>
<p>浏览器缓存位置一般分为四类： Service Worker–&gt;Memory Cache–&gt;Disk Cache–&gt;Push Cache</p>
<h2 id="强缓存"><a href="#强缓存" class="headerlink" title="强缓存"></a>强缓存</h2><p>强缓存是当我们访问URL的时候，不会向服务器发送请求，直接从缓存中读取资源，但是会返回200的状态码。</p>
<h3 id="如何设置强缓存"><a href="#如何设置强缓存" class="headerlink" title="如何设置强缓存"></a>如何设置强缓存</h3><p>我们第一次进入页面，请求服务器，然后服务器进行应答，浏览器会根据 response Header 来判断是否对资源进行缓存，如果响应头中 expires、pragma 或者 cache-control 字段，代表这是强缓存，浏览器就会把资源缓存在 memory cache 或 disk cache 中。</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/20220306145630.png" alt="image"></p>
<h3 id="控制缓存的字段"><a href="#控制缓存的字段" class="headerlink" title="控制缓存的字段"></a>控制缓存的字段</h3><p>主要有以下几个：expires、Cache-control、pragma</p>
<h4 id="expires"><a href="#expires" class="headerlink" title="expires"></a>expires</h4><p>是HTTP1.0控制网页缓存的字段，值为一个时间戳，准确来讲是格林尼治时间，服务器返回该请求结果缓存的到期时间，意思是，再次发送请求时，如果未超过过期时间，直接使用该缓存，如果过期了则重新请求。<br>有个缺点，就是它判断是否过期是用本地时间来判断的，本地时间是可以自己修改的。</p>
<h4 id="Cache-Control"><a href="#Cache-Control" class="headerlink" title="Cache-Control"></a>Cache-Control</h4><p>是HTTP1.1中控制网页缓存的字段，当Cache-Control都存在时，Cache-Control优先级更高，主要取值为：</p>
<ul>
<li>public：资源客户端和服务器都可以缓存。</li>
<li>privite：资源只有客户端可以缓存。</li>
<li>no-cache：客户端缓存资源，但是是否缓存需要经过协商缓存来验证。</li>
<li>no-store：不使用缓存。</li>
<li>max-age：缓存保质期。</li>
</ul>
<p><strong>Cache-Control使用了max-age相对时间，解决了expires的问题。</strong></p>
<h4 id="pragma"><a href="#pragma" class="headerlink" title="pragma"></a>pragma</h4><p>这个是HTTP1.0中禁用网页缓存的字段，其取值为no-cache，和 Cache-Control 的 no-cache 效果一样。</p>
<h2 id="缓存位置"><a href="#缓存位置" class="headerlink" title="缓存位置"></a>缓存位置</h2><p>上面我们说，强缓存我们会把资源房放到memory cache 和 disk cache中，那什么资源放在memory cache，什么资源放在disk cache中？</p>
<p><strong>存存储图像和网页</strong>等资源主要缓存在disk cache，<strong>操作系统缓存文件</strong>等资源大部分都会缓存在memory cache中。具体操作浏览器自动分配，看谁的资源利用率不高就分给谁。</p>
<p>可以看到memory cache请求时间都是0ms，这个是不是太神奇了，这方面我来梳理下。</p>
<p>查找浏览器缓存时会按顺序查找: Service Worker–&gt;Memory Cache–&gt;Disk Cache–&gt;Push Cache。</p>
<h3 id="Service-Worker"><a href="#Service-Worker" class="headerlink" title="Service Worker"></a>Service Worker</h3><p>是运行在浏览器背后的独立线程，一般可以用来实现缓存功能。使用 Service Worker 的话，传输协议必须为 HTTPS。因为 Service Worker 中涉及到请求拦截，所以必须使用 HTTPS 协议来保障安全。Service Worker 的缓存与浏览器其他内建的缓存机制不同，它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存，并且缓存是持续性的。</p>
<h3 id="Memory-Cache"><a href="#Memory-Cache" class="headerlink" title="Memory Cache"></a>Memory Cache</h3><p>内存中的缓存，主要包含的是当前中页面中已经抓取到的资源，例如页面上已经下载的样式、脚本、图片等。读取内存中的数据肯定比磁盘快，内存缓存虽然读取高效，可是缓存持续性很短，会随着进程的释放而释放。一旦我们关闭 Tab 页面，内存中的缓存也就被释放了。</p>
<h3 id="Disk-Cache"><a href="#Disk-Cache" class="headerlink" title="Disk Cache"></a>Disk Cache</h3><p>存储在硬盘中的缓存，读取速度慢点，但是什么都能存储到磁盘中，<strong>比之 Memory Cache 胜在容量和存储时效性上</strong>。</p>
<p>在所有浏览器缓存中，Disk Cache 覆盖面基本是最大的。它会根据 HTTP Herder 中的字段判断哪些资源需要缓存，哪些资源可以不请求直接使用，哪些资源已经过期需要重新请求。并且即使在跨站点的情况下，相同地址的资源一旦被硬盘缓存下来，就不会再次去请求数据。<strong>绝大部分的缓存都来自 Disk Cache</strong>。</p>
<p>memory cache 要比 disk cache 快的多。举个例子：从远程 web 服务器直接提取访问文件可能需要500毫秒(半秒)，那么磁盘访问可能需要10-20毫秒，而内存访问只需要100纳秒，更高级的还有 L1缓存访问(最快和最小的 CPU 缓存)只需要0.5纳秒。</p>
<h3 id="prefetch-cache-预取缓存"><a href="#prefetch-cache-预取缓存" class="headerlink" title="prefetch cache(预取缓存)"></a>prefetch cache(预取缓存)</h3><p>link标签上带了prefetch，再次加载会出现。</p>
<p>prefetch 是预加载的一种方式，被标记为 prefetch 的资源，<strong>将会被浏览器在空闲时间加载</strong>。</p>
<h3 id="Push-Cache"><a href="#Push-Cache" class="headerlink" title="Push Cache"></a>Push Cache</h3><p>Push Cache（推送缓存）是 HTTP/2 中的内容，<strong>当以上三种缓存都没有命中时，它才会被使用</strong>。它只在会话（Session）中存在，一旦会话结束就被释放，并且缓存时间也很短暂，在Chrome浏览器中只有5分钟左右，同时它也并非严格执行HTTP头中的缓存指令。</p>
<h2 id="协商缓存"><a href="#协商缓存" class="headerlink" title="协商缓存"></a>协商缓存</h2><p>协商缓存就是强缓存失效后，浏览器携带缓存标识向服务器发送请求，由服务器根据缓存标识来决定是否使用缓存的过程。</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/20220306145714.png" alt="image"></p>
<p>主要有以下两种情况：</p>
<ol>
<li>协商缓存生效，返回304</li>
</ol>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220216161804242.png" alt="image-20220216161804242"></p>
<ol start="2">
<li>协商缓存失效，返回200和请求结果</li>
</ol>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220216161818821.png" alt="image-20220216161818821"></p>
<h3 id="如何设置协商缓存"><a href="#如何设置协商缓存" class="headerlink" title="如何设置协商缓存"></a>如何设置协商缓存</h3><h4 id="Last-Modified-If-Modified-Since"><a href="#Last-Modified-If-Modified-Since" class="headerlink" title="Last-Modified / If-Modified-Since"></a>Last-Modified / If-Modified-Since</h4><p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/20220306145815.png" alt="last-modified"></p>
<p>Last-Modified 是服务器响应请求时，返回该资源文件在服务器最后被修改的时间。</p>
<p>If-Modified-Since 则是客户端再次发起该请求时，携带上次请求返回的 Last-Modified 值，通过此字段值告诉服务器该资源上次请求返回的最后被修改时间。服务器收到该请求，发现请求头含有If-Modified-Since 字段，则会根据 If-Modified-Since 的字段值与该资源在服务器的最后被修改时间做对比，若服务器的资源最后被修改时间大于 If-Modified-Since 的字段值，则重新返回资源，状态码为200；否则则返回304，代表资源无更新，可继续使用缓存文件。</p>
<h4 id="Etag-If-None-Match"><a href="#Etag-If-None-Match" class="headerlink" title="Etag / If-None-Match"></a>Etag / If-None-Match</h4><p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/20220306145848.png" alt="etag"></p>
<p>Etag是服务器响应请求时，返回当前资源文件的一个唯一标识(由服务器生成)。</p>
<p>If-None-Match 是客户端再次发起该请求时，携带上次请求返回的唯一标识 Etag 值，通过此字段值告诉服务器该资源上次请求返回的唯一标识值。服务器收到该请求后，发现该请求头中含有If-None-Match，则会根据 If-None-Match 的字段值与该资源在服务器的 Etag 值做对比，一致则返回304，代表资源无更新，继续使用缓存文件；不一致则重新返回资源文件，状态码为200。</p>
<blockquote>
<p>Etag / If-None-Match 优先级高于 Last-Modified / If-Modified-Since，同时存在则只有 Etag / If-None-Match 生效。</p>
</blockquote>
<p>如果资源被重复生成，而内容不变，则Etag更精确</p>
<h2 id="强缓存与协商缓存的区别"><a href="#强缓存与协商缓存的区别" class="headerlink" title="强缓存与协商缓存的区别"></a>强缓存与协商缓存的区别</h2><ol>
<li><p>强缓存不发请求到服务器，所以有时候资源更新了浏览器还不知道，但是协商缓存会发请求到服务器，所以资源是否更新，浏览器肯定知道。</p>
</li>
<li><p>大部分web服务器都默认开启协商缓存。</p>
</li>
</ol>
<h2 id="缓存方案"><a href="#缓存方案" class="headerlink" title="缓存方案"></a>缓存方案</h2><p>目前的项目大多使用这种缓存方案的：</p>
<ul>
<li><p>HTML: 协商缓存；</p>
</li>
<li><p>css、js、图片：强缓存，文件名带上hash。</p>
</li>
</ul>
<h2 id="刷新对于强缓存和协商缓存的影响"><a href="#刷新对于强缓存和协商缓存的影响" class="headerlink" title="刷新对于强缓存和协商缓存的影响"></a>刷新对于强缓存和协商缓存的影响</h2><ol>
<li><p>当 ctrl+f5 强制刷新网页时，直接从服务器加载，跳过强缓存和协商缓存。</p>
</li>
<li><p>当 f5 刷新网页时，跳过强缓存，但是会检查协商缓存。</p>
</li>
<li><p>浏览器地址栏中写入 URL，回车 浏览器发现缓存中有这个文件了，不用继续请求了，直接去缓存拿。强缓存有效，协商缓存有效。</p>
</li>
</ol>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220216161428643.png" alt="image-20220216161428643"></p>
<p>首先通过 <code>Cache-Control</code> 验证强缓存是否可用</p>
<ul>
<li>如果强缓存可用，直接使用</li>
<li>否则进入协商缓存，即发送 HTTP 请求，服务器通过请求头中的`If-Modified-Since<code>或者</code>If-None-Match`这些<strong>条件请求</strong>字段检查资源是否更新<ul>
<li>若资源更新，返回资源和200状态码</li>
<li>否则，返回304，告诉浏览器直接从缓存获取资源</li>
</ul>
</li>
</ul>

  </div>
</article>



        
          <div id="footer-post-container">
  <div id="footer-post">

    <div id="nav-footer" style="display: none">
      <ul>
         
          <li><a href="/">首页</a></li>
         
          <li><a href="/tags/">标签</a></li>
         
          <li><a href="/categories/">分类</a></li>
         
          <li><a href="/archives/">归档</a></li>
         
          <li><a target="_blank" rel="noopener" href="http://github.com/twitzz">项目</a></li>
         
          <li><a href="/about/">关于</a></li>
         
          <li><a href="/search/">搜索</a></li>
        
      </ul>
    </div>

    <div id="toc-footer" style="display: none">
      <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%BC%BA%E7%BC%93%E5%AD%98"><span class="toc-number">1.</span> <span class="toc-text">强缓存</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A6%82%E4%BD%95%E8%AE%BE%E7%BD%AE%E5%BC%BA%E7%BC%93%E5%AD%98"><span class="toc-number">1.1.</span> <span class="toc-text">如何设置强缓存</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%8E%A7%E5%88%B6%E7%BC%93%E5%AD%98%E7%9A%84%E5%AD%97%E6%AE%B5"><span class="toc-number">1.2.</span> <span class="toc-text">控制缓存的字段</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#expires"><span class="toc-number">1.2.1.</span> <span class="toc-text">expires</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Cache-Control"><span class="toc-number">1.2.2.</span> <span class="toc-text">Cache-Control</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#pragma"><span class="toc-number">1.2.3.</span> <span class="toc-text">pragma</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BC%93%E5%AD%98%E4%BD%8D%E7%BD%AE"><span class="toc-number">2.</span> <span class="toc-text">缓存位置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Service-Worker"><span class="toc-number">2.1.</span> <span class="toc-text">Service Worker</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Memory-Cache"><span class="toc-number">2.2.</span> <span class="toc-text">Memory Cache</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Disk-Cache"><span class="toc-number">2.3.</span> <span class="toc-text">Disk Cache</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#prefetch-cache-%E9%A2%84%E5%8F%96%E7%BC%93%E5%AD%98"><span class="toc-number">2.4.</span> <span class="toc-text">prefetch cache(预取缓存)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Push-Cache"><span class="toc-number">2.5.</span> <span class="toc-text">Push Cache</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8D%8F%E5%95%86%E7%BC%93%E5%AD%98"><span class="toc-number">3.</span> <span class="toc-text">协商缓存</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%A6%82%E4%BD%95%E8%AE%BE%E7%BD%AE%E5%8D%8F%E5%95%86%E7%BC%93%E5%AD%98"><span class="toc-number">3.1.</span> <span class="toc-text">如何设置协商缓存</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Last-Modified-If-Modified-Since"><span class="toc-number">3.1.1.</span> <span class="toc-text">Last-Modified &#x2F; If-Modified-Since</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Etag-If-None-Match"><span class="toc-number">3.1.2.</span> <span class="toc-text">Etag &#x2F; If-None-Match</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%BC%BA%E7%BC%93%E5%AD%98%E4%B8%8E%E5%8D%8F%E5%95%86%E7%BC%93%E5%AD%98%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">4.</span> <span class="toc-text">强缓存与协商缓存的区别</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BC%93%E5%AD%98%E6%96%B9%E6%A1%88"><span class="toc-number">5.</span> <span class="toc-text">缓存方案</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%88%B7%E6%96%B0%E5%AF%B9%E4%BA%8E%E5%BC%BA%E7%BC%93%E5%AD%98%E5%92%8C%E5%8D%8F%E5%95%86%E7%BC%93%E5%AD%98%E7%9A%84%E5%BD%B1%E5%93%8D"><span class="toc-number">6.</span> <span class="toc-text">刷新对于强缓存和协商缓存的影响</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%BB%E7%BB%93"><span class="toc-number">7.</span> <span class="toc-text">总结</span></a></li></ol>
    </div>

    <div id="share-footer" style="display: none">
      <ul>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.facebook.com/sharer.php?u=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/"><i class="fab fa-facebook fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://twitter.com/share?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&text=浏览器缓存"><i class="fab fa-twitter fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.linkedin.com/shareArticle?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&title=浏览器缓存"><i class="fab fa-linkedin fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://pinterest.com/pin/create/bookmarklet/?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&is_video=false&description=浏览器缓存"><i class="fab fa-pinterest fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="mailto:?subject=浏览器缓存&body=Check out this article: https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/"><i class="fas fa-envelope fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://getpocket.com/save?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&title=浏览器缓存"><i class="fab fa-get-pocket fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://reddit.com/submit?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&title=浏览器缓存"><i class="fab fa-reddit fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.stumbleupon.com/submit?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&title=浏览器缓存"><i class="fab fa-stumbleupon fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://digg.com/submit?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&title=浏览器缓存"><i class="fab fa-digg fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.tumblr.com/share/link?url=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&name=浏览器缓存&description="><i class="fab fa-tumblr fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://news.ycombinator.com/submitlink?u=https://danyuan30.gitee.io/2022/02/11/frontend/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/&t=浏览器缓存"><i class="fab fa-hacker-news fa-lg" aria-hidden="true"></i></a></li>
</ul>

    </div>

    <div id="actions-footer">
        <a id="menu" class="icon" href="#" onclick="$('#nav-footer').toggle();return false;"><i class="fas fa-bars fa-lg" aria-hidden="true"></i> 菜单</a>
        <a id="toc" class="icon" href="#" onclick="$('#toc-footer').toggle();return false;"><i class="fas fa-list fa-lg" aria-hidden="true"></i> 目录</a>
        <a id="share" class="icon" href="#" onclick="$('#share-footer').toggle();return false;"><i class="fas fa-share-alt fa-lg" aria-hidden="true"></i> 分享</a>
        <a id="top" style="display:none" class="icon" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');"><i class="fas fa-chevron-up fa-lg" aria-hidden="true"></i> 返回顶部</a>
    </div>

  </div>
</div>

        
        <footer id="footer">
  <div class="footer-left">
    Copyright &copy;
    
    
    2021-2022
    柯里的语法糖
  </div>
  <div class="footer-right">
    <nav>
      <ul>
        <!--
       --><li><a href="/">首页</a></li><!--
     --><!--
       --><li><a href="/tags/">标签</a></li><!--
     --><!--
       --><li><a href="/categories/">分类</a></li><!--
     --><!--
       --><li><a href="/archives/">归档</a></li><!--
     --><!--
       --><li><a target="_blank" rel="noopener" href="http://github.com/twitzz">项目</a></li><!--
     --><!--
       --><li><a href="/about/">关于</a></li><!--
     --><!--
       --><li><a href="/search/">搜索</a></li><!--
     -->
      </ul>
    </nav>
  </div>
</footer>

    </div>
    <!-- styles -->



  <link rel="preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" crossorigin="anonymous" onload="this.onload=null;this.rel='stylesheet'"/>


    <!-- jquery -->
 
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" crossorigin="anonymous"></script> 




<!-- clipboard -->

  
    <script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.7/clipboard.min.js" crossorigin="anonymous"></script> 
  
  <script type="text/javascript">
  $(function() {
    // copy-btn HTML
    var btn = "<span class=\"btn-copy tooltipped tooltipped-sw\" aria-label=\"复制到粘贴板!\">";
    btn += '<i class="far fa-clone"></i>';
    btn += '</span>'; 
    // mount it!
    $(".highlight table").before(btn);
    var clip = new ClipboardJS('.btn-copy', {
      text: function(trigger) {
        return Array.from(trigger.nextElementSibling.querySelectorAll('.code')).reduce((str,it)=>str+it.innerText+'\n','')
      }
    });
    clip.on('success', function(e) {
      e.trigger.setAttribute('aria-label', "复制成功!");
      e.clearSelection();
    })
  })
  </script>


<script src="/js/main.js"></script>

<!-- search -->

<!-- Google Analytics -->

<!-- Baidu Analytics -->

<!-- Cloudflare Analytics -->

<!-- Umami Analytics -->

<!-- Disqus Comments -->

<!-- utterances Comments -->

</body>
</html>
